using System;

namespace KanbanBoard.Server.Command.DomainModel {
    public class Task {
        private string description;
        private readonly Priority priority = Priority.Undefined;
        private Lane lane = Lane.Null;
        private Column column = Column.Null;

        private Task() {}

        internal Task(Lane lane, Column column) {
            Move().To(column);
            Move().To(lane);
        }

        public Movement Move() {
            return new Movement(this);
        }

        public Prioritization Prioritize() {
            return new Prioritization(this);
        }

        public void ChangeDescription(string newDescription) {
            description = newDescription;
        }

        public void Delete() {
            Move().To(Column.Null);
            Move().To(Lane.Null);
            priority.PutBelow(Priority.Undefined);
        }

        public class Prioritization {
            private readonly Task task;

            internal Prioritization(Task task) {
                this.task = task;
            }

            public void Below(Task higherPriorityTask) {
                task.priority.PutBelow(higherPriorityTask.priority);
            }

            public void Above(Task lowerPriorityTask) {
                task.priority.PutBelow(lowerPriorityTask.priority);
            }

            public void StartNewPriorityChain() {
                task.priority.StartNewPriorityChain();
            }
        }

        public class Movement {
            private readonly Task task;

            internal Movement(Task task) {
                this.task = task;
            }

            public void To(Column column) {
                column.PullFrom(task, task.column);
                task.column = column;
            }

            public void To(Lane lane) {
                lane.MoveFrom(task, task.lane);
                task.lane = lane;
            }
        }
    }
}